package cn.gx.kevin.common.ui;

import cn.gx.kevin.common.utils.SysConfigParams;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 页面datagrid配置
 * 
 * @author kevin.huang
 *
 */
public class DataGridHelper {

    public final static Logger logger = org.slf4j.LoggerFactory.getLogger(DataGridHelper.class);
    private static HashMap<String, HashMap<String, DataGrid>> modeCfgCache =
        new HashMap<String, HashMap<String, DataGrid>>();

    static PathMatchingResourcePatternResolver resoler = new PathMatchingResourcePatternResolver();

    static String classPath = "classpath:/datagrid/";

    public static void initDatagrid() throws Throwable {
        initToMap();
    }

    private static void initToMap() {

    }

    /**
     * @Title: getDataGridCfg @Description: 获取datagrid配置 ,产品模式下，先读缓存如果没有再读取文件，开发模式读取文件 @param model 配置文件模块路径 @param
     *         gridid 配置节点的gridid @return json字符串 @throws
     */
    /*
     * public static DataGrid getDataGridCfg(String model,String gridid,String lang)
     * throws Throwable{ return getDataGridCfg(model,gridid,gridid,lang); }
     */

    public static DataGrid readGridFromXml(Document doc, String gridid) {

        NodeList list = doc.getElementsByTagName("datagrid");

        DataGrid grid = null;
        for (int i = 0; i < list.getLength(); i++) {
            Element node = (Element)list.item(i);
            String gid = node.getAttribute("id");
            if (StringUtils.isEmpty(gridid)) {
                gridid = gid;
            }
            if (gid.equalsIgnoreCase(gridid)) {
                grid = new DataGrid();
                String title_g = node.getAttribute("title");
                String methodsObject = node.getAttribute("methodsObject");
                String pagesize = node.getAttribute("pagesize");
                String oprCol = node.getAttribute("oprCol");
                String checkbox = node.getAttribute("checkbox");
                String url = node.getAttribute("url");
                grid.setCheckbox(checkbox.equalsIgnoreCase("true") ? true : false);
                grid.setTitle(title_g);
                grid.setUrl(url);
                grid.setId(gridid);
                grid.setMethodsObject(methodsObject);
                grid.setOprCol(oprCol.equalsIgnoreCase("true") ? true : false);
                grid.setPagesize(Integer.parseInt(pagesize));
                NodeList toolbarlist = node.getElementsByTagName("toolbar");
                if (toolbarlist.getLength() > 0) {
                    Node node1 = node.getElementsByTagName("toolbar").item(0);
                    NodeList toolbarButList = ((Element)node1).getChildNodes();
                    List<Object> toolbar = new ArrayList<>();
                    for (int k = 0, len = toolbarButList.getLength(); k < len; ++k) {
                        Node node2 = toolbarButList.item(k);
                        short nodeType = node2.getNodeType();
                        if (nodeType == 1) {
                            Element n = (Element)node2;
                            String tagName = n.getTagName();
                            if(tagName.equals("btn")){
                                node2Button(methodsObject, toolbar, String.valueOf( k), n);
                            }else if(tagName.equals("g")){ //分组按钮
                                List<ClientButton> glist = new ArrayList<>();
                                NodeList nodeList = ((Element)node2).getChildNodes();
                                for(int m = 0,mlen = nodeList.getLength() ;m < mlen; m++){
                                    Node node3 = nodeList.item(m);
                                    if(node3.getNodeType() == 1){
                                        Element el = (Element) node3;
                                        node2Button(methodsObject, glist, k+"_"+m, el);
                                    }
                                }
                                toolbar.add(glist);
                            }
                        }
                    }
                    grid.setToolbar(toolbar);
                }
                toolbarlist = node.getElementsByTagName("lineButton");
                if (toolbarlist.getLength() > 0) {
                    NodeList lineButList = ((Element)toolbarlist.item(0)).getChildNodes();
                    List<ClientButton> lineButton = new ArrayList<ClientButton>();
                    for (int k = 0, len = lineButList.getLength(); k < len; ++k) {
                        Node node1 = lineButList.item(k);
                        short nodeType = node1.getNodeType();
                        if (nodeType == 1) {
                            Element n = (Element)node1;
                            node2Button(methodsObject, lineButton, String.valueOf( k), n);
                        }
                    }
                    grid.setLineButton(lineButton);
                }
                StringBuffer colBuffer = new StringBuffer();
                colBuffer.append("[");
                // 多个cols 动态表头
                NodeList colList = ((Element)node.getElementsByTagName("grid").item(0)).getElementsByTagName("cols");
                int len = colList.getLength();
                for (int k = 0; k < len; ++k) {
                    colBuffer.append("[");
                    NodeList cols = ((Element)colList.item(k)).getElementsByTagName("col");
                    int col_len = cols.getLength();
                    for (int n = 0; n < col_len; n++) {
                        Element node1 = (Element)cols.item(n);
                        String colspan = node1.getAttribute("colspan");
                        String title = node1.getAttribute("title");
                        colBuffer.append("{\"title\":\"" + title + "\",");
                        if (colspan != null && !colspan.equals("")) {
                            colBuffer.append("\"colspan\":" + colspan);
                            String rowspan = node1.getAttribute("rowspan");
                            if (rowspan != null && !rowspan.equals("")) {
                                colBuffer.append(",\"rowspan\":" + rowspan);
                            }
                            colBuffer.append("}");
                        } else {
                            String field = node1.getAttribute("field");
                            String width = node1.getAttribute("width");
                            String align = node1.getAttribute("align");
                            String sortable = node1.getAttribute("sortable");
                            String formatter = node1.getAttribute("formatter");
                            String openTip = node1.getAttribute("openTip");
                            if (sortable == null) {
                                sortable = "False";
                            }
                            if(StringUtils.isNotEmpty(openTip)){
                                colBuffer.append("\"openTip\":true,");
                            }
                            colBuffer.append("\"field\":\"" + field + "\",");
                            colBuffer.append("\"width\":\"" + width + "\",");
                            colBuffer.append("\"align\":\"" + align + "\",");
                            colBuffer.append("\"sortable\":" + sortable + ",");
                            colBuffer.append("\"formatter\":\"" + formatter + "\"}");

                        }
                        if (n < col_len - 1) {
                            colBuffer.append(",");
                        }
                    }
                    colBuffer.append("]");
                    if (k < len - 1) {
                        colBuffer.append(",");
                    }

                }
                colBuffer.append("]");
                grid.setColString(colBuffer.toString());
                break;
            }
        }
        return grid;
    }

    private static void node2Button(String methodsObject, List toolbar, String  idSubfix, Element n) {
        ClientButton but = nodeToClientButton(n, idSubfix);
        but.setMethodsObject(methodsObject);
        toolbar.add(but);
        NodeList childrens = n.getElementsByTagName("btn");
        if (childrens != null && childrens.getLength() > 0) {
            for (int k1 = 0, len1 = childrens.getLength(); k1 < len1; ++k1) {
                Element n1 = (Element)childrens.item(k1);
                ClientButton child = nodeToClientButton(n1, idSubfix + k1);
                child.setMethodsObject(methodsObject);
                but.setChildren(child);
            }
        }
    }

    /**
     * @Title: getDataGridCfg @Description: 获取datagrid配置 ,产品模式下，先读缓存如果没有再读取文件，开发模式读取文件 @param model 配置文件模块路径 @param
     *         filePrefix文件前缀 @param gridid 配置节点的gridid @param lang 语言环境 @return json字符串 @throws
     */
    public static DataGrid getDataGridCfg(String model, String filePrefix, String gridid) throws Throwable {
        if (StringUtils.isEmpty(filePrefix)) {
            filePrefix = gridid;
        }
        HashMap<String, DataGrid> cfgCache = modeCfgCache.get(model);
        if (cfgCache == null) {
            cfgCache = new HashMap<String, DataGrid>();
            modeCfgCache.put(model, cfgCache);
        }
        if (!SysConfigParams.isDevModel()) {
            DataGrid tmp = cfgCache.get(gridid);
            if (tmp != null) {
                return tmp;
            }
        }
        String file = model + filePrefix + "-datagrid.xml";
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        String location;
        Resource resource;
        InputStream xmlin;

        if (SysConfigParams.isDefaultClassPath) { // 是否是默认class路径
            location = classPath + file;
            resource = resoler.getResource(location);
            xmlin = resource.getInputStream();
        } else {
            location =
                SysConfigParams.configHome + File.separator + "datagrid" + File.separator + File.separator + file;
            try {
                resource = resoler.getResource(location);
                xmlin = resource.getInputStream();
            } catch (Exception ex) {
                String location1 = classPath + File.separator + file;
                resource = resoler.getResource(location1);
                xmlin = resource.getInputStream();
                logger.debug("the file {} is not found ,apply {} ", location, location1);
            }
        }
        Document doc = builder.parse(xmlin);
        DataGrid grid = readGridFromXml(doc, gridid);
        if (!SysConfigParams.isDevModel()) {// 生产模式保存到缓存
            cfgCache.put(gridid, grid);
        }
        return grid;
    }

    private static ClientButton nodeToClientButton(Element n, String idsubfix) {
        String text = n.getAttribute("text");
        String iconCls = n.getAttribute("iconCls");
        String handler = n.getAttribute("handler");
        String cmd = n.getAttribute("cmd");
        String params = n.getAttribute("params");
        String disabled = n.getAttribute("disabled");
        ClientButton but = new ClientButton("line_btn_" + idsubfix, text, handler, cmd, iconCls);
        if (disabled != null && disabled.equals("true")) {
            but.setDisabled(true);
        }
        String color = n.getAttribute("color");
        if (color != null) {
            but.setColor(color);
        }

        if (params != null) {
            String[] p_arr = params.split(";");
            for (String k_v : p_arr) {
                if (!"".equals(k_v)) {
                    String[] kv = k_v.split(":");
                    but.setParams(kv[0], kv[1]);
                }
            }
        }
        return but;
    }
}
